﻿<html>
<body>
    1.*OOP编程，并不是类越多越好，类的划分是为了封装，但分类的基础是抽象，具有相同属性和功能的对象的抽象集合才是类。

    2.*软件设计真正要做的许多内容，就是发现职责并把那些职责相互分离。如果你能想到多于一个的动机去改变一个类，那么这个类
       就具有多于一个的职责。

    3.*无论模块多么封闭，都会存在一些无法对其封闭的变化。设计人员必须对于他设计的模块应该对哪种变化做出选择。
      *编写最初代码时，假设变化不会发生。当变化发生时，我们就创建抽象来隔离以后发生的同类变化。
       面对需求，对程序的改动是通过增加新代码进行，而不是更改现有的代码。

    4.里氏代换原则：*子类型必须能够替代掉它们的父类型。
                    *只有当子类可以替换掉父类，软件单位的功能不受到影响时，父类才能真正的被复用，而子类也能够在父类的
                     基础上增加新的行为。

    5.代理模式的应用：*远程代理：为一个对象在不同的地址空间提供局部代表。(例如WS中的添加服务引用)
                      *虚拟代理：根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。
                                 (如一个大网页中很多图片，文字是全部打开，图片是一张张下载打开的，就是用
                                   虚拟代理替代了真实的图片)
                      *安全代理：用来控制真实对象的访问权限。
                      *智能指引：当调用真实的对象时，代理处理另外一些事。

    6.工厂模式与简单工厂：*工厂模式实现时，客户端需要决定实例化哪一个工厂来实现运算类，选择判断的问题还是存在的，也就是说，
                           工厂模式把简单工厂的内部逻辑判断移到了客户端来进行。想要加功能，简单工厂是修改工厂类，工厂模式是
                           修改客户端。
                          *工厂模式克服了简单工厂违背开闭原则的缺点，又保持了封装对象创建过程的优点。
                           缺点是每加一个产品，就需要多加一个产品工厂的类，增加了额外的开发量。

    7.原型模式：*其实就是从一个对象再创建另外一个可定制的对象，而且不需要知道任何创建的细节。
                 一般在初始化的信息不发生变化的情况下，克隆是最好的方法。既隐藏了对象创建的细节，又对性能大大的提高。
                 (避免了反复初始化的消耗)。动态地获取了对象运行时的状态。

    8.深复制与浅复制：
            浅复制:*创建一个新对象，将当前对象的非静态字段复制到新对象，
                    如果字段是值类型的，则对该字段执行逐位复制。如果是引用类型，则复制引用但不复制引用的对象。
                    ***因此，原始对象及副本引用同一个对象。***
            深复制:*把引用对象的变量指向复制过的新对象，而不是原有的被引用的对象。
            可以看出，深拷贝和浅拷贝之间的区别在于是否复制了子对象

    9.模板方法模式：*当我们完成在某一细节层次一致的一个过程或一系列步骤，但其个别步骤在更详细的层次上的实现可能不同时，
                     我们通常考虑用模板方法模式进行处理。

    10.迪米特法则：*强调的前提是在类的结构设计上，每一个类都应当尽量降低成员的访问权限。根本思想就是强调了类之间的松耦合。
                    类之间的耦合越弱，越有利于复用，一个处在弱耦合的类被修改时，不会对有关系的类造成波及。

    11.外观模式的使用：*在设计初期阶段，应该要有意识的将不同的两个层分离。比如三层架构，可以考虑在BLL和DAL之间，VIEW和BLL之间
                        建立外观Facade，这样可以为复杂的子系统提供一个简单的接口。
                       *其次在开发阶段，子系统往往因为不断的重构演化而变得越来越复杂，增加外观Facade可以提供一个简单的接口，
                        减少他们直接的依赖。
                       *第三，在维护一个遗留的大型系统时，可能这个系统已经非常难以维护和扩展了，但新需求必须要依赖于它。
                        此时可以为新系统开发一个外观类，来提供设计粗糙或高度复杂的遗留代码的一个简单接口，让新系统与Facade
                        对象交互，Facade与遗留代码交互所有复杂的工作。

    12.建造者模式：*Builder:为创建一个Product对象的各个部件指定的抽象接口
                   *ConcreteBuilder:具体建造者，实现Builder接口，构造和装配各个部件。
                   *Product：具体的产品，如DEMO中的小人。
                   *Director:构建一个使用Builder接口的对象。
       *什么时候使用建造者模式：
                   *用于创建一些复杂的对象，这些对象内部构建间的建造顺序通常是稳定的，但对象内部的构建通常面临着复杂的变化。
                    好处就是使得构造代码与表示代码分离，由于建造者隐藏了该产品是如何组装的，所以若需要改变一个产品的内部表示，
                    只需要再定义一个具体的建造者就可以了。

    13.观察者模式：*使用的动机是将一个系统分割成一系列相互协作的类有一个很不好的副作用，那就是需要维护相关对象间的一致性。
                    我们不希望为了维持一致性而使各类紧密耦合。
                   *当一个对象的改变需要同时改变其他对象，而且它不知道具体有多少对象有待改变时，应考虑使用观察者模式。
                   *当一个抽象模型有两个方面，其中一方面依赖于另一方面，这时用观察者模式可以将这两者封装在独立的对象中使它们
                    各自独立的改变和复用。总的来讲，观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象，
                    而不是依赖于具体。从而使得各自的变化都不会影响另一边。
        *观察者模式的不足：尽管已经用了依赖倒置原则，但是抽象通知者还是依赖抽象观察者，也就是说，万一没有了抽象观察者
                           这样的接口，这通知的功能就行不通了。另外就是每个具体的观察者，它不一定是要调用更新方法，可能是打开，
                           可能是关闭，根本不是同名方法。
        *使用委托：*委托就是一种引用方法的类型。一旦为委托分配了方法，委托将与该方法具有完全相同的行为。委托方法的使用可以像其他
                    任何方法一样，具有参数和返回值。委托可以看作是对函数的抽象，是函数的'类'，委托的实例将代表一个具体的函数。
                   *一个委托可以搭载多个方法，所有方法被依次唤起，它可以使得委托对象所搭载的方法并不需要属于同一个类。
        *使用委托的前提：委托对象所搭载的所有方法必须具有相同的原型和形式，也就是拥有相同的参数列表和返回值类型。

    14.反射+配置文件：*所有在用简单工厂的地方，都可以考虑用反射技术来去除if或switch，解除分支判断带来的耦合。

    15.状态模式：*主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列
                  类当中，可以把复杂的判断逻辑化。
                 好处：*将与特定状态相关的行为局部化，并且将不同状态的行为分割开来。意思就是将特定的状态相关的行为都放入一个对象中，
                       由于所有与状态相关的代码都存在于某个ConcreteState中，所以通过定义新的子类可以很容易地增加新的状态和转换。
                       *目的就是为了消除庞大的条件分支语句，大的分支判断难以修改和扩展，状态模式通过把各种状态转移逻辑分布到State
                       的子类之间，来减少相互依赖。
                       *当一个对象的行为取决于它的状态，并且它必须在运行时刻根据状态改变它的行为时，就可以考虑使用状态模式。

    16.适配器模式：*使用一个已经存在的类，但如果它的接口，也就是它的方法和你要求的不相同时，就应该考虑使用适配器模式。
                   *当两个类所做的事情相同或相似，但是具有不同的接口时也要使用它。
                   *优点：客户代码可以统一调用同一接口，代码简洁，直接，不需要修改原有的方法。
                   *一般适用于后期维护，在双方都不太容易修改的时候使用。

    17.备忘录模式：*把要保存的细节都封装在Memento中，哪一天要更改保存的细节也不影响客户端的使用。
                   *适用于功能比较复杂的，但需要维护或记录属性历史的类，或者需要保存的属性只是众多属性中的一小部分时，
                    Originator可以根据保存的Memento信息还原到前一状态。
                   *如果在某个系统中使用命令模式时，需要实现命令的撤销功能，那么命令模式可以使用备忘录模式来存储可撤销操作的
                    状态。
                   *可以把复杂的对象内部信息对其他的对象屏蔽起来。

    18.组合模式：*透明方式：在Component中声明所有用来管理子对象的方法，其中包括Add,Remove方法等。
                            这样实现Component接口的所有子类都具备了Add和Remove方法。这样做的好处就是叶节点和分枝节点对于外界
                            没有区别，具备完全一致的行为接口。问题就是Leaf本身不具备Add和Remove功能，实现了没有意义。
                 *安全方式：在Component中不声明Add,Remove方法等。那么子类的Leaf也就不需要去实现它，而是在Composite声明所有
                            用来管理子类对象的方法。这样就不会实现没有意义的接口。问题就是不够透明，树叶和树枝将不具有相同的
                            接口，客户端的调用需要做相应的判断，带来不便。
                 *好处：定义了包含人力资源部和财务部这些基本对象和分公司、办事处等组合对象的类层次结构。基本对象可以被组合成
                        更复杂的组合对象，而这个组合对象又可以被组合，这样不断的递归下去，客户代码中，任何用到基本对象的地方
                        都可以使用组合对象了。用户不用关心到底是处理一个叶节点还是组合对象，也就不用为定义组合而写条件判断语句了。
                        简单来说，组合模式可以一致地使用组合结构和单个对象。

    19.多线程时的单例模式：
                 *多线程的程序中，多个线程如果同时访问单例模式的GetInstance方法，会有可能造成创建多个实例。
                  此时需要用lock来处理，lock是确保当一个线程位于代码的临界区时，另一个线程不进入临界区，如果其他线程试图进入锁定的
                  代码，则它将一直等待，直到该对象被释放。
                 *静态初始化的方式是在自己被加载时就将自己实例化，被称为饿汉式单例类。
                  普通的单例模式是要在第一次被引用时，才会将自己实例化，被称为懒汉式单例类。

    20.桥接模式：*对象的继承关系是在编译时就定义好了，所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的
                  依赖关系，以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时，如果继承下来的实现不适合解决
                  新的问题，则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限定了复用性。
                 *合成/聚合复用原则：尽量使用合成/聚合，尽量不要使用类继承。
                  聚合表示一种弱的拥有关系，体现的是A对象可以包含B对象，但B对象不是A对象的一部分；
                  合成则是一种强的拥有关系，体现了严格的部分和整体的关系，部分和整体的生命周期是一样的。
                  例如，大雁的翅膀和大雁就是合成关系，而大雁和雁群是聚合关系。
                 *合成/聚合复用的好处：优先使用对象的合成/聚合将有助于你保持每个类被封装，并被集中在单个任务上。这样类和
                  类继承层次会保持较小规模，并且不太可能增长为不可控制的庞然大物。
                 *盲目使用继承会造成麻烦，继承是一种强耦合的结构。父类变，子类就必须改变。
                 *桥接模式的抽象与它的对象分离，并不是说让抽象类与其派生类分离。实现指的是抽象类和它的派生类用来实现自己的对象。
                  也就是说，实现系统可能有多角度分类，每一种分类都有可能变化，那么就把这种多角度分离出来让它们独立变化，减少
                  它们之间的耦合。

    21.命令模式：*优点：能比较容易的设计一个命令队列；
                        在需要的情况下，可以比较容易地将命令写入日志；
                        允许接受请求的一方决定是否要否决请求；
                        可以容易的实现对请求的撤销和重做；
                        由于新加进的具体命令类不影响其他的类，因此增加新的具体命令类很容易；
                        把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
                 *如果不知道需不需要撤销/恢复操作时，要不要提前使用命令模式以备以后使用呢：
                  敏捷开发原则告诉我们，不要为代码添加基于猜测的，实际不需要的功能。如不过不清楚一个系统是否需要命令模式，
                  一般就不要急着去实现它，事实上，在需要的时候通过重构实现这个模式并不困难，只有在真正需要如撤销/恢复操作
                  等功能时，把原来的代码重构为命令模式才有意义。

    22.职责链模式：*当客户提交一个请求时，请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这就使得接收者和发送者都没有
                    对方明确的信息，且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接，它们仅需保持一个指向
                    其后继者的引用，而不需保持它所有的候选接收者的引用。
                   *可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。也要当心，一个请求极有可能到了链的
                    末端都得不到处理，或者因为没有正确配置而得不到处理。

    23.中介者模式：*中介者模式很容易在系统中应用，也很容易误用。当系统出现了"多对多"交互复杂的对象群时，不要急于使用中介者模式，
                    而要先反思你的系统在设计上是不是合理。
           优缺点：*优点是减少了各个Colleague的耦合，使得可以独立地改变和复用各个Colleague类和Mediator。其次，由于把对象如何协作
                    进行了抽象，将中介作为一个独立的概念并将其封装在一个对象中，这样关注的对象就从对象各自本身的行为转移到它们
                    之间的交互上，也就是站在一个更宏观的角度去看待系统。
                   *缺点是ConcreteMediator控制了集中化，于是就把交互复杂性变成了中介者的复杂性，这就使得中介者会变得比任何一个
                    ConcreteColleague都复杂。
             应用：*用于一组对象以定义良好但是复杂的方式进行通信的场合，已经想定制一个分布在多个类中的行为，而又不想生成太多的
                    子类的场合。

    24.享元模式：*享元模式可以避免大量非常相似类的开销。在程序设计中，有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例
                  除了几个参数外基本上都是相同的，有时就能大幅度减少需要实例化的类的数量。如果能把那些参数移到类实例的外面，
                  在方法调用时将它们传递进来，就可以通过共享大幅度地减少单个实例的数目。

</body>
</html>